library(tidyverse)
library(sf)
library(nngeo)
library(leaflet)
library(fs)
library(osmdata)
library(osrm)
El objetivo de este informe es presentar la problemática de la accesibilidad geográfica de los barrios vulnerables de la Ciudad Autónoma de Buenos Aires al conglomerado de escuelas que conforman la oferta educativa de la ciudad. La información generada en este breve análisis intentará oficiar de insumo para la planificación de políticas públicas dirigidas a lograr una mayor inclusión socioespacial en el ámbito educativo. Para llevar a cabo esta empresa, realizaremos una comparativa, en términos de proximidad y la accesibilidad geográfica, entre de tres barrios vulnerables y tres barrios de clase media / alta de la ciudad, que oficie de diagnóstico preliminar de la situación que permita la elaboración de una propuesta de gestión pública a posteriori.
Tomaremos la definición de barrio utilizada por el Ministerio de Desarrollo y Hábitat del Gobierno de la Ciudad Autónoma de Buenos Aires, en tanto comunidad o conjunto habitacional, con identidad propia dentro de la ciudad, que cumple con la normativa urbanística y sanitaria vigente, presentando un tejido urbano regular y condiciones socioeconómicas estables, sin indicadores de fragilidad o riesgo social elevados. En el caso de barrios vulnerables, se los considera como zonas precarias y vulnerables en materia de infraestructura habitacional, con características sociales y urbanas particulares, generalmente vinculadas a la informalidad. Entre los mismos podemos distinguir: Villas, asentamientos precarios, barrios municipales, barrios urbanizados, y núcleos habitacionales transitorio. Por otro lado, de acuerdo al Ministerio de Habitat y Desarrollo, un barrio es una unidad territorial en la que está subdividida CABA. Hay 48 barrios oficiales, cada uno con historia, límites y características socioculturales propias. Administrativamente, los barrios están definidos por una ordenanza de 1968 y funcionan como divisiones de tercer orden (después de la ciudad y las comunas). La noción de barrio es tanto administrativa como identitaria y social, reflejando características culturales y de pertenencia de sus habitantes
url_barrios2 <- "https://cdn.buenosaires.gob.ar/datosabiertos/datasets/ministerio-de-desarrollo-humano-y-habitat/barrios-populares"
url_comunas <- "https://cdn.buenosaires.gob.ar/datosabiertos/datasets/ministerio-de-educacion/comunas/comunas.geojson"
url_barrioscaba <- "https://cdn.buenosaires.gob.ar/datosabiertos/datasets/ministerio-de-educacion/barrios/barrios.geojson"
url_educativos <- "https://cdn.buenosaires.gob.ar/datosabiertos/datasets/ministerio-de-educacion/establecimientos-educativos/establecimientos_educativos.geojson"
url_radiocensalcaba <- "https://cdn.buenosaires.gob.ar/datosabiertos/datasets/direccion-general-de-estadisticas-y-censos/informacion-censal-por-radio/caba_radios_censales.geojson"
url_radiosamba <- "https://cdn.produccion.gob.ar/cdn-cep/amba-aportantes/Shapes.rar"
url_radiosocioeco <- "https://cdn.produccion.gob.ar/cdn-cep/amba-aportantes/Empleo-AMBA.csv"
#Cargamos el mapa de barrios y le transformamos el crs
barrioscm_caba <- st_read(url_barrioscaba)
st_crs(barrioscm_caba)
sum(!st_is_valid(barrioscm_caba))
barrioscm_caba <- st_transform(barrioscm_caba, 5347)
comunas_caba <- st_read("https://cdn.buenosaires.gob.ar/datosabiertos/datasets/ministerio-de-educacion/comunas/comunas.geojson")
td <- tempdir()
download.file(url = paste(url_barrios2,
"barrios-populares-badata.zip",
sep = "/"),
destfile = fs::path(td, "barrios-populares-badata.zip") )
unzip(zipfile = fs::path(td, "barrios-populares-badata.zip"),
exdir = td)
barrios_vul <- read_sf(fs::path(td, "barrios_vulnerables.shp"))
rm(td)
st_crs(barrios_vul)
sum(!st_is_valid(barrios_vul))
barrios_vul <- st_transform(barrios_vul, 5347)
#Cargamos un mapa de radiocensales de CABA para que nos oficie de mapa base para la visualización
radio_bsas <- st_read(url_radiocensalcaba)
## Reading layer `informacion_censal_por_radio_wgs84' from data source
## `https://cdn.buenosaires.gob.ar/datosabiertos/datasets/direccion-general-de-estadisticas-y-censos/informacion-censal-por-radio/caba_radios_censales.geojson'
## using driver `GeoJSON'
## Simple feature collection with 3554 features and 15 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -58.53152 ymin: -34.70529 xmax: -58.33514 ymax: -34.52755
## Geodetic CRS: WGS 84
st_crs(radio_bsas)
## Coordinate Reference System:
## User input: WGS 84
## wkt:
## GEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["geodetic latitude (Lat)",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["geodetic longitude (Lon)",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]]
sum(!st_is_valid(radio_bsas))
## [1] 0
radio_bsas <- st_transform(radio_bsas, 5347)
En un primer acercamiento, observamos una distribución territorial más bien periferica del conjunto habitacional, comunmente denominado como Villa Miseria; si bien el mismo tiende a concentrarse más bien en zona sur de la ciudad -caso “Villa 21-24 Zabaleta” en la comuna de Barracas-, en la zona norte encontramos a la “Villa 31: Barrio Padre Carlos Mugica” en la comuna de retiro. Por otro lado, al posar la lente en el centro de la ciudad, encontramos asentamientos y nucleos habitacionales tomados, cuyo caso más destacable es el de Villa Fraga, ubicada junto los terrenos ferroviarios del ferrocarril Urquiza. Si bien usualmente se la se lo denomina como villa, por su antiguedad y precariedad en el nivel de organizacion, el asentamiento no cumple con las caracteristicas estipuladas por el Ministerio de Habitat y Desarrollo para dicha nominación, sino que se posiciona más bien en la categoría de “Asentamiento precario urbano”, actualmente bajo proceso de integracion socio-urbana.
#Primera visualizacion barrios pop en radio censales
ggplot() +
geom_sf(data = radio_bsas, fill = "grey90", color = "black", size = 0.1) +
geom_sf(data = barrios_vul, fill = "red", color = "red", alpha = 1) +
labs(title = "Ubicación de barrios vulnerables de CABA - Radiocensales",
fill = "Comuna") +
theme_minimal()
Para este trabajo tomaremos tres barrios vulnerables, espacialmente distantes entre sí, los cuales cumplen con la denominación de villa. Se trata de la Villa 31: Barrio Padre Carlos Mugica , ubicado en Retiro, comuna 1, al limite de la zona noreste de la ciudad;en segundo lugar, la Villa 21-24: Barrio Zavaleta, ubicada en el linde sureste de la ciudad, entre los barrios de Barracas y Pompeya, dentro de la Comuna 4; finalmente la Villa 15: Barrio General Belgrano, usualmente nominada como “Ciudad Oculta” en Villa Lugano, comuna 8. Las tres, por su antiguedad, extension y niveles de organización cumplen con el concepto de Villa, en tanto conjunto extenso y estable de nucleos habitacionales respectivos, precarios y vulnerables a nivel de infraestructura. Tomaremos 8 radiocensales de muestra, aquellos con mayor superficie, en el caso de cada una de las villas seleccionadas .
#Hacemos el space join entre los barrios y los radiocensales, para unir solo las partes de la geometria, es decir los radiocensales, que se intersectan con los barrios populares
radios2 <- st_transform(radios2, 5347)
barrios_vul <- st_transform(barrios_vul, 5347)
barrios_vul_rs <- st_join(radios2, barrios_vul, join = st_intersects) %>%
filter(NOMBRE %in% c("Villa 31","Villa 31 - Padre Mugica",
"Villa 21-24", "Villa 15 - Ciudad Oculta")) %>%
mutate(NOMBRE = case_when(
NOMBRE == "Villa 15 - Ciudad Oculta" ~ "Villa_15",
NOMBRE == "Villa 31 - Padre Mugica" ~ "Villa_31",
NOMBRE == "Villa 21-24" ~ "Villa_21_24",
TRUE ~ "Villa_31"
)) %>%
rename(barrios_nom = NOMBRE)
barriosvul_selec <- barrios_vul_rs %>%
group_by(barrios_nom) %>%
arrange(desc(Superficie)) %>%
slice_head(n = 8) %>%
ungroup()
#rm(barrios_vul)
rm(barrios_vul_rs)
leaflet() %>%
addProviderTiles("CartoDB.Positron") %>%
addPolygons(
data = st_transform(barriosvul_selec, 4326),
fillColor = "red",
color = "darkred",
weight = 1,
fillOpacity = 0.6,
label = ~barrios_nom
) %>%
addControl(
html = "Muestra de 8 radiocensales por Barrio Seleccionado",
position = "topright"
) %>%
addLegend(
position = "bottomright",
title = "Barrios seleccionados",
colors = rep("red", length(unique(barriosvul_selec$barrios_nom))),
labels = unique(barriosvul_selec$barrios_nom),
opacity = 0.6
)
educ <- st_read(url_educativos)
sum(!st_is_valid(educ))
educ <- st_transform(educ, 5347) %>%
select(escuela = nam , tipo_gestion = ges, nivel = nen_mde, tipo = tip, geom_edu = geometry)
educ_sna <- educ %>% filter(!is.na(tipo_gestion)) #sacamos los na
rm(educ)
Por otro lado, tenemos la red de escuelas de la Ciudad de Buenos Aires, la cual consta de 2764 centros educativos, presentando un patron de concentración hacia la zona del macro alrededores, con una dispersión en los barrios ubicados en los márgenes, especialmente al sur.
ggplot() +
geom_sf(data = radio_bsas, fill = "grey95", color = "black", size = 0.1) +
geom_sf(
data = educ_sna,
aes(color = tipo_gestion),
size = 1,
shape = 21,
stroke = 0.6) +
scale_color_manual(values = c("Estatal" = "yellow",
"Privada" = "purple"))+
theme_minimal() +
labs(
title = "Escuelas dentro de buffers de barrios vulnerables",
color = "Tipo de gestión"
)
buffvul_500 <- barriosvul_selec %>% st_buffer(500) %>% mutate(buffer = "500m")
buffvul_1000 <- barriosvul_selec %>% st_buffer(1000) %>% mutate(buffer = "1000m")
buffvul_2000 <- barriosvul_selec %>% st_buffer(2000) %>% mutate(buffer = "2000m")
buffersvul_bind <- bind_rows(buffvul_500, buffvul_1000, buffvul_2000)
escuelasvul_buffer <- st_join(educ_sna, buffersvul_bind, join = st_intersects) %>%
filter(!is.na(barrios_nom))
conteo_escuelasvul <- escuelasvul_buffer %>%
filter(!is.na(barrios_nom), !is.na(buffer)) %>%
st_drop_geometry() %>%
distinct(escuela, buffer, barrios_nom) %>%
group_by(barrios_nom, buffer) %>%
summarise(total = n(), .groups = "drop")
Centrandonos en las muestras de radiocensales pertenecientes a los tres barrios vulnerables seleccionados, como aproximación preliminar evaluamos la proximidad geografica de los radiocensales respecto las escuelas, explorando la cantidad de establecimientos que entran en la cobertura de buffers de 500, 1000 y 2000 metros. Entre los barrios vulnerables, en terminos de distancia geografica cabe destacar el caso de la Villa 15 al sur en el radio de cobertura de 500 metros, alcanzando una abarcar un total de 49 escuelas, casi el doble que en el caso de la Villa 21-24 y la 31, las cuales alcanzan una cobertura de 24 y 22, respectivamente. Dicha diferencia se atempera respecto de la Villa 21-24 en el radio de cobertura 1000 metros, evidenciando una diferencia de 13 escuelas mientras que en el caso de la Villa 31, se mantiene un margen de 29 escuelas de diferencia. En el radio de cobertura de 2000 metros, las diferencias en terminos de cantidad se reducen bastante más siendo en ambos casos, (Villa 21-24 y Villa 31) de menos de 10 escuelas
tablavul_resumen <- conteo_escuelasvul %>%
pivot_wider(
names_from = buffer,
values_from = total
) %>%
mutate(Sum = rowSums(across(where(is.numeric))))
print (tablavul_resumen)
## # A tibble: 3 × 5
## barrios_nom `1000m` `2000m` `500m` Sum
## <chr> <int> <int> <int> <dbl>
## 1 Villa_15 70 153 49 272
## 2 Villa_21_24 57 160 24 241
## 3 Villa_31 41 151 22 214
ggplot(conteo_escuelasvul, aes(x = barrios_nom, y = total, fill = buffer)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_manual(values = c(
"500m" = "#1b9e77",
"1000m" = "#d95f02",
"2000m" = "#7570b3"
)) +
labs(title = "Escuelas cercanas a barrios vulnerables",
x = "Barrio", y = "Cantidad de escuelas", fill = "Distancia") +
theme_minimal()
conteovul_ges <- escuelasvul_buffer %>%
filter(!is.na(barrios_nom), !is.na(buffer)) %>%
st_drop_geometry() %>%
distinct(escuela, barrios_nom, tipo_gestion) %>%
group_by(barrios_nom, tipo_gestion) %>%
summarise(total = n(), .groups = "drop")
tablavul_ges <- conteovul_ges %>%
pivot_wider(
names_from = tipo_gestion,
values_from = total
) %>%
mutate(Sum = rowSums(across(where(is.numeric))))
print (tablavul_ges)
## # A tibble: 3 × 4
## barrios_nom Estatal Privada Sum
## <chr> <int> <int> <dbl>
## 1 Villa_15 124 29 153
## 2 Villa_21_24 137 23 160
## 3 Villa_31 81 70 151
ggplot(escuelasvul_buffer, aes(x = barrios_nom, fill = tipo_gestion)) +
geom_bar( position = "dodge") +
scale_fill_manual(values = c(
"Estatal" = "#1b9e77",
"Privada" = "#d95f02" )) +
labs(title = "Conteo de escuelas vulnerables por gestion",
x = "Barrio", y = "Cantidad de escuelas", fill = "tipo_gestion (Gestion)") +
theme_minimal()
Otra diferencia, se observa respecto del tipo de gestion, resultando particularmente notoria en los casos sur, es decir Villa 15 y Villa 21_24, registrandose una diferencia de mas del tiple de escuelas de gestion publica respecto de la privada. Cabe destacar que la situación difiere de manera contundente en el caso de la zona norta de Retiro con una diferencia de 9 escuelas unicamente. Coincidimos con Di Virgilio (20..), respecto de la concentración de escuelas de gestión privada, desde el centro hacia el norte, principalmente.
escuelasvul_filtradas <- st_filter(educ_sna, buffersvul_bind)
ggplot() +
geom_sf(data = radio_bsas, fill = "grey95", color = "black", size = 0.1) +
geom_sf(
data = buffersvul_bind,
aes(fill = buffer),
color = "red",alpha = 0.05) +
geom_sf(
data = escuelasvul_filtradas,
aes(color = tipo_gestion),
size = 2) +
scale_fill_manual(
values = c("500m" = "blue",
"1000m" = "skyblue",
"2000m" = "red")) +
scale_color_manual(values = c("Estatal" = "yellow",
"Privada" = "purple"))+
theme_minimal() +
labs(
title = "Escuelas vulnerables en buffers de radioscensales de cobertura ",
subtitle = "Radio de cobertura a 500m, 1000m y 2000m - Colores por gestion",
fill = "Rango de distancia",
color = "Tipo de gestion"
)
ggplot() +
geom_sf(data = radio_bsas, fill = "grey90", color = "black", size = 0.1) + # Mapa fondo
geom_sf(data = buffersvul_bind, aes(color = buffer), fill = NA, size = 2) + # Buffers
# Escuelas en cobertura
geom_sf(data = escuelasvul_buffer, aes(fill = tipo_gestion),
color = "black", size = 1, shape = 21, alpha = 0.6) +
scale_color_manual(
values = c("500m" = "red",
"1000m" = "blue",
"2000m" = "green")
) +
scale_fill_manual(
values = c("Privada" = "purple",
"Estatal" = "yellow")
) +
labs(
title = "Escuelas vulnerables en radios de cobertura",
subtitle = "Facetado por barrio vulnerable",
color = "Cobertura (Buffer)",
fill = "Tipo de gestión"
) +
theme_minimal() +
facet_wrap(~ barrios_nom)
leaflet() %>%
addProviderTiles("CartoDB.Positron") %>%
# Base: radio de Buenos Aires
addPolygons(
data = st_transform(radio_bsas, 4326),
fillColor = "transparent",
color = "black",
weight = 1,
group = "Base"
) %>%
# Buffers solo con borde coloreado
addPolygons(
data = st_transform(buffersvul_bind, 4326),
fillColor = "transparent",
color = ~case_when(
buffer == "500m" ~ "red",
buffer == "1000m" ~ "blue",
buffer == "2000m" ~ "green",
TRUE ~ "black"
),
weight = 2,
fillOpacity = 0,
label = ~buffer,
group = "Buffers",
highlightOptions = highlightOptions(weight = 3, color = "grey"),
options = pathOptions(interactive = FALSE)
) %>%
# Escuelas como puntos
addCircleMarkers(
data = st_transform(escuelasvul_filtradas, 4326),
color = ~ifelse(tipo_gestion == "Privada", "purple", "yellow"),
radius = 2,
fillOpacity = 0.8,
popup = ~paste("Escuela:", escuela, "<br>",
"Tipo gestión:", tipo_gestion),
group = "Escuelas"
) %>%
# Leyenda
addLegend(
position = "bottomright",
colors = c("red", "blue", "green"),
labels = c("500m", "1000m", "2000m"),
title = "Buffer - Distancia"
) %>%
# Control de capas
addLayersControl(
overlayGroups = c("Buffers", "Escuelas"),
options = layersControlOptions(collapsed = FALSE)
)
# Pasamos los barrios vulnerables a geometría de puntos (centroide o punto interno)
barriosvul_puntos <- barriosvul_selec %>%
st_point_on_surface() %>%
select(Id, barrios_nom, CO_FRAC_RA, TIPO_ASENT, MANZANA, Superficie, geometry)
## Warning: st_point_on_surface assumes attributes are constant over geometries
# 2. Buffer de 500m (manteniendo CRS proyectado)
buffvul500_punto <- barriosvul_puntos %>%
st_buffer(500) %>%
mutate(buffer = "500m")
# 3. Filtrar escuelas dentro del buffer
escuelasvul_500 <- st_filter(educ_sna, buffvul500_punto)
# 4. Transformar a 4326 solo para visualización
barriosvul_puntos_wgs <- st_transform(barriosvul_puntos, 4326)
buffvul500_punto_wgs <- st_transform(buffvul500_punto, 4326)
escuelasvul_500_wgs <- st_transform(escuelasvul_500, 4326)
En la siguiente tabla podemos ver una minima de 10 segundos, una media de 13 minutos y medio, y una maxima de 28.10 minutos, siendo la mediana 16 minutos exactos. Con lo cual, para escuelas de a 500 metros (5 cuadras se puede llegar a tardar por lo general alrededor de 16 minutos)
tabla_tiemposvul_500 <- osrmTable(src = barriosvul_puntos_wgs, dst = escuelasvul_500)
df_tiemposvul_500 <- as.data.frame(tabla_tiemposvul_500$durations)
df_tiemposvul_500$radio_id <- rownames(df_tiemposvul_500)
df_tiemposvul_larga_500 <- df_tiemposvul_500 %>%
pivot_longer(
cols = -radio_id,
names_to = "escuela_id",
values_to = "tiempo_min") %>%
mutate(buffer = "500m")
summary(df_tiemposvul_larga_500$tiempo_min)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.10 2.40 16.00 13.59 18.70 28.10
# Agrupamos por radio censal y sacamos la media para graficar
df_tiemposvul_media <- df_tiemposvul_larga_500 %>%
group_by(radio_id) %>%
summarise(tiempo_min = mean(tiempo_min), .groups = 'drop') %>%
arrange(radio_id) %>%
mutate(radio_id = factor(radio_id, levels = radio_id))
print(df_tiemposvul_media)
## # A tibble: 24 × 2
## radio_id tiempo_min
## <fct> <dbl>
## 1 1 11.7
## 2 10 12.5
## 3 11 12.5
## 4 12 12.5
## 5 13 12.5
## 6 14 12.5
## 7 15 12.5
## 8 16 12.5
## 9 17 16.6
## 10 18 16.9
## # ℹ 14 more rows
Aqui tenemos el tiempo promedio para llegar a las escuelas en un radio de cobertura de 500 metros, por radiocensal el cual varia entre 11 y 17 minutos.
ggplot(df_tiemposvul_media, aes(x = reorder(radio_id, tiempo_min), y = tiempo_min)) +
geom_col(fill = "steelblue") +
coord_flip() +
labs(
title = "Tiempo promedio a escuelas (Radio de cobertura 500m)",
x = "Radio censal",
y = "Tiempo promedio (minutos)"
) +
theme_minimal()
radio_socioeco <- read.csv(url_radiosocioeco, fileEncoding = "latin1")
mapa_eco <- left_join(radios2, radio_socioeco, by = c("CO_FRAC_RA" = "LINK" ) ) %>%
filter(!is.na(Remuneracion_media))
rm(radio_socioeco)
cuartiles <- quantile(mapa_eco$Remuneracion_media, probs = c(0.25, 0.50, 0.75), na.rm = TRUE)
bairescm_q <- mapa_eco %>%
filter(provincia_id == 2, Remuneracion_media > 30000) %>% #Recortamos CABA
mutate(cluster = case_when(
Remuneracion_media <= cuartiles[1] ~ "Clase baja", #Dividimos el ingreso en cuartiles
Remuneracion_media <= cuartiles[2] ~ "Clase media",
Remuneracion_media <= cuartiles[3] ~ "Clase media alta",
TRUE ~ "Clase alta"
))
barrioscm_caba <- st_read(url_barrioscaba)
## Reading layer `barrios' from data source
## `https://cdn.buenosaires.gob.ar/datosabiertos/datasets/ministerio-de-educacion/barrios/barrios.geojson'
## using driver `GeoJSON'
## Simple feature collection with 48 features and 6 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -58.53152 ymin: -34.70529 xmax: -58.33516 ymax: -34.52649
## Geodetic CRS: WGS 84
st_crs(barrioscm_caba)
## Coordinate Reference System:
## User input: WGS 84
## wkt:
## GEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["geodetic latitude (Lat)",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["geodetic longitude (Lon)",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]]
sum(!st_is_valid(barrioscm_caba))
## [1] 0
barrioscm_caba <- st_transform(barrioscm_caba, 5347)
barrioscm_gg <- barrioscm_caba %>% filter(nombre %in% c("Almagro", "Caballito", "Palermo"))
barrios_cm_sj <- st_join(bairescm_q, barrioscm_caba, join = st_intersects)
barrioscm_sjs <- barrios_cm_sj %>%
select(CO_FRAC_RA, geometry, Remuneracion_media, cluster, nombre, comuna, perimetro_, area_metro) %>%
rename(barrios_nom = nombre)
rm(bairescm_q)
rm(barrioscm_caba)
Para llevar la comparativa en terminos de proximidad y accesibilidad geografica con barrios de clase media y alta, a fines de mantener una coherencia metodológica tomamos tres barrios, clasificados de acuerdo a su nivel de ingreso, como barrios de clase media baja, en el caso de Almagro, para clase media el barrio de Caballito, y para clase media alta a Palermo.
#Cargamos un mapa de radiocensales de CABA para que nos oficie de mapa base para la visualización
radio_bsas <- st_read(url_radiocensalcaba)
## Reading layer `informacion_censal_por_radio_wgs84' from data source
## `https://cdn.buenosaires.gob.ar/datosabiertos/datasets/direccion-general-de-estadisticas-y-censos/informacion-censal-por-radio/caba_radios_censales.geojson'
## using driver `GeoJSON'
## Simple feature collection with 3554 features and 15 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -58.53152 ymin: -34.70529 xmax: -58.33514 ymax: -34.52755
## Geodetic CRS: WGS 84
st_crs(radio_bsas)
## Coordinate Reference System:
## User input: WGS 84
## wkt:
## GEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["geodetic latitude (Lat)",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["geodetic longitude (Lon)",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]]
sum(!st_is_valid(radio_bsas))
## [1] 0
radio_bsas <- st_transform(radio_bsas, 5347)
ggplot() +
geom_sf(data = radio_bsas, fill = "grey90", color = "black") +
geom_sf(data = barrioscm_gg, aes(fill = nombre), color = "white", size = 0.2, alpha = 0.2) +
scale_fill_manual (values = c("Almagro" = "red",
"Caballito" = "green",
"Palermo" = "blue")) +
labs(title = "Selección de barrios de Clase Media/Alta")
barrioscm_selec <- barrioscm_sjs %>%
filter(barrios_nom == "Palermo" & cluster == "Clase alta" |
barrios_nom == "Caballito" & cluster == "Clase media alta"|
barrios_nom == "Almagro" & cluster == "Clase media" ) %>%
group_by(barrios_nom) %>%
arrange(desc (Remuneracion_media)) %>%
slice_head(n=8) %>%
ungroup()
#rm(barrioscm_sjs)
De esa selección tomamos 8 radiocensales de acuerdo al nivel de ingreso mas alto. Los dos barrios de clase media se encuentran en el centro geografico y urbano de la ciudad, salvo Palermo ubicado en zona norte, lindante con Retiro.
ggplot() +
geom_sf(data = radio_bsas, fill = "grey90", color = "black") +
geom_sf(data = barrioscm_selec, aes(fill = barrios_nom), color = "white", size = 0.2) +
scale_fill_brewer(palette = "Set1") +
labs(
title = "Muestra de radios censales por barrio",
subtitle = "8 Radios censales por barrio elegido",
fill = "barrios_nom (Barrios)",
color = "black"
) +
theme_minimal()
buff_cm_500 <- barrioscm_selec %>% st_buffer(500) %>% mutate(buffer = "500m")
buff_cm_1000 <- barrioscm_selec %>% st_buffer(1000) %>% mutate(buffer = "1000m")
buff_cm_2000 <- barrioscm_selec %>% st_buffer(2000) %>% mutate(buffer = "2000m")
buffers_cm_bind <- bind_rows(buff_cm_500, buff_cm_1000, buff_cm_2000)
escuelas_cmbuffer <- st_join(educ_sna, buffers_cm_bind, join = st_intersects) %>%
filter(!is.na(barrios_nom))
conteo_escuelas_cm <- escuelas_cmbuffer %>%
filter(!is.na(barrios_nom), !is.na(buffer)) %>%
st_drop_geometry() %>%
distinct(escuela, buffer, barrios_nom) %>%
group_by(barrios_nom, buffer) %>%
summarise(total = n(), .groups = "drop")
tablacm_resumen <- conteo_escuelas_cm %>%
pivot_wider(
names_from = buffer,
values_from = total
) %>%
mutate(Sum = rowSums(across(where(is.numeric))))
print (tablacm_resumen)
## # A tibble: 3 × 5
## barrios_nom `1000m` `2000m` `500m` Sum
## <chr> <int> <int> <int> <dbl>
## 1 Almagro 302 636 131 1069
## 2 Caballito 243 529 113 885
## 3 Palermo 259 563 96 918
En primer lugar, cabe mencionar que, en terminos relativos, los totales no muestran variaciones significativas, destacandose ligeramente el barrio de Almagro, del mismo modo que en cada uno de los radios de cobertura, a pesar de que en terminos estrictos, Caballito es el centro geografico, que de todos modos le sigue con una pequeña diferencia. En el radio de cobertura media (1000 metros), Palermo aventaja a Caballito por 16 escuelas -en terminos relativos, apenas un 3.20%- y una diferencia similar -del %3.11 en este caso- para el radio de cobertura más lejano (es decir 2000 metros).
ggplot(conteo_escuelas_cm, aes(x = barrios_nom, y = total, fill = buffer)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_manual(values = c(
"500m" = "#1b9e77",
"1000m" = "#d95f02",
"2000m" = "#7570b3"
)) +
labs(title = "Escuelas de barrios de clase media/alta por Radio de Cobertura",
x = "Barrio", y = "Cantidad de escuelas", fill = "Distancia (Cobertura)") +
theme_minimal()
conteocm_ges <- escuelas_cmbuffer %>%
filter(!is.na(barrios_nom), !is.na(buffer)) %>%
st_drop_geometry() %>%
distinct(escuela, barrios_nom, tipo_gestion) %>%
group_by(barrios_nom, tipo_gestion) %>%
summarise(total = n(), .groups = "drop")
tablacm_ges <- conteocm_ges %>%
pivot_wider(
names_from = tipo_gestion,
values_from = total
) %>%
mutate(Sum = rowSums(across(where(is.numeric))))
print (tablacm_ges)
## # A tibble: 3 × 4
## barrios_nom Estatal Privada Sum
## <chr> <int> <int> <dbl>
## 1 Almagro 356 280 636
## 2 Caballito 322 207 529
## 3 Palermo 289 274 563
Vemos que en todos los casos, siempre el numero de escuelas publicas sobrepasa al de establecimientos privados, destacando el caso de Palermo, en el cual el numero de estos ultimos se encuentra practicamente igualado al de los públicos.
ggplot(conteocm_ges, aes(x = barrios_nom, y = total, fill = tipo_gestion)) +
geom_col(position = "dodge") +
scale_fill_manual(values = c(
"Estatal" = "#1b9e77",
"Privada" = "#d95f02")) +
labs(
title = "Escuelas cercanas a barrios de clase media/alta",
x = "Barrio",
y = "Cantidad de escuelas",
fill = "Gestión"
) +
theme_minimal()
buffers_cm_bind$buffer <- factor(buffers_cm_bind$buffer,
levels = c("500m", "1000m", "2000m"))
ggplot() +
# Mapa base
geom_sf(data = radio_bsas, fill = "grey90", color = "black", size = 0.1) +
# Buffers con transparencia
geom_sf(data = buffers_cm_bind,
aes(fill = buffer),
color = "red", alpha = 0.2) +
# Escuelas dentro de los buffers
geom_sf(data = escuelas_cmbuffer,
aes(color = tipo_gestion),
size = 2) +
# Colores para buffers y gestión
scale_fill_manual(values = c("500m" = "blue",
"1000m" = "skyblue",
"2000m" = "red")) +
scale_color_manual(values = c("Privada" = "purple",
"Estatal" = "yellow")) +
labs(title = "Escuelas por radio de cobertura en radioscensales",
subtitle = "Radio de cobertura a 500m, 1000m y 2000m - Colores por gestión",
fill = "Distancia",
color = "Gestión") +
theme_minimal()
En ambos mapas, total y facetado, puede observarse la concentracion del escuelas hacia el centro, reflejandose una merma hacia zona norte, radio de cobertura en el cual se encuentra Palermo. En el caso de este ultimo barrio, la cobertura media y la mas amplia alcanzan a cubrir la zona norcentrica, reflejandose una ligera diferencia en la cantidad de escuelas incluidas en el radio mas pequeño, respecto de Caballito y Almagro que toman de lleno la zonas mas multitudinaria en materia de establecimientos.
escuelascm_filtradas <- st_filter(educ_sna, buffers_cm_bind)
ggplot() +
geom_sf(data = radio_bsas, fill = "grey90", color = "black", linewidth = 0.1) + # Mapa fondo
geom_sf(data = buffers_cm_bind, aes(color = buffer), fill = NA, linewidth = 2) + # Buffers
geom_sf(data = escuelascm_filtradas, aes(fill = tipo_gestion), # Escuelas en cobertura
color = "black", size = 1, shape = 21, alpha = 0.6) +
scale_color_manual( # color de bordes buffers
values = c("500m" = "red",
"1000m" = "blue",
"2000m" = "green")
) +
scale_fill_manual( # Color de puntos de escuela
values = c("Privada" = "purple",
"Estatal" = "yellow")
) +
labs(
title = "Escuelas por radios de cobertura en radioscensales",
subtitle = "Facetado por barrio",
color = "Cobertura (Buffer)",
fill = "Tipo de gestion"
) +
theme_minimal() +
facet_wrap(~ barrios_nom)
buffers_cm_bind_wgs <- st_transform(buffers_cm_bind, 4326)
escuelascm_filtradas_wgs <- st_transform(escuelascm_filtradas, 4326)
escuelascm_filtradas_wgs <- escuelascm_filtradas_wgs %>%
mutate(
escuela = iconv(escuela, from = "", to = "UTF-8"),
tipo_gestion = iconv(tipo_gestion, from = "", to = "UTF-8")
)
buffers_cm_bind_wgs <- buffers_cm_bind_wgs %>%
mutate(
buffer = iconv(buffer, from = "", to = "UTF-8")
)
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addPolylines(
data = buffers_cm_bind_wgs,
color = ~case_when(
buffer == "500m" ~ "red",
buffer == "1000m" ~ "blue",
buffer == "2000m" ~ "green"
),
weight = 2,
opacity = 0.8,
label = ~paste("Cobertura:", buffer),
options = pathOptions(interactive = FALSE),
group = "Buffers"
) %>%
addCircleMarkers(
data = escuelascm_filtradas_wgs,
color = "black",
fillColor = ~case_when(
tipo_gestion == "Privada" ~ "purple",
tipo_gestion == "Estatal" ~ "yellow",
TRUE ~ "grey" # para "Sin dato"
),
fillOpacity = 0.8,
radius = 5,
group = "Escuelas"
)
#Para la geoconsulta trabajamos con geometria de puntos, mas liviana.
barrioscm_puntos <- barrioscm_selec %>%
st_point_on_surface()%>%
select(CO_FRAC_RA, barrios_nom, cluster, Remuneracion_media, area_metro, geometry) %>%
arrange(desc(area_metro))
buffcm500_punto <- barrioscm_puntos %>% st_buffer(500) %>% mutate(buffer = "500m")
#Rebuffereo
escuelascm_500 <- st_filter(educ_sna, buffcm500_punto)
#Filtrado de escuelas dentro de cada buffer
#Configuramos OSRM en modo a pie
options(osrm.profile = "foot")
#Transformamos el CRS a 4326 para la geocon
barrioscm_puntos <- st_transform(barrioscm_puntos, 4326)
escuelascm_500 <- st_transform(escuelascm_500, 4326)
#Calculamos tiempos para 500m
tabla_tiemposcm_500 <- osrmTable(src = barrioscm_puntos, dst = escuelascm_500)
df_tiemposcm_500 <- as.data.frame(tabla_tiemposcm_500$durations)
df_tiemposcm_500$radio_id <- rownames(df_tiemposcm_500)
df_tiemposcm_larga_500 <- df_tiemposcm_500 %>%
pivot_longer(
cols = -radio_id,
names_to = "id_escuela",
values_to = "tiempo_min") %>%
mutate(buffer = "500m")
print(df_tiemposcm_larga_500)
## # A tibble: 6,264 × 4
## radio_id id_escuela tiempo_min buffer
## <chr> <chr> <dbl> <chr>
## 1 1 1 31.8 500m
## 2 1 2 31.8 500m
## 3 1 3 31.8 500m
## 4 1 4 15.5 500m
## 5 1 5 15.5 500m
## 6 1 6 40.1 500m
## 7 1 7 40.1 500m
## 8 1 8 35.8 500m
## 9 1 9 35.8 500m
## 10 1 10 32.4 500m
## # ℹ 6,254 more rows
summary(df_tiemposcm_larga_500$tiempo_min)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.00 25.57 41.20 42.95 57.50 115.40
Desde la accesibilidad geografica, tenemos una media de viaje a pie de casi 43 minutos, con una Maxima cercana a las 2 horas y una mediana ligeramente superior a los 41 minutos.
df_resumen <- df_tiemposcm_larga_500 %>%
group_by(radio_id) %>%
summarise(tiempo_promedio = mean(tiempo_min, na.rm = TRUE))
ggplot(df_resumen, aes(x = reorder(radio_id, tiempo_promedio), y = tiempo_promedio)) +
geom_col(fill = "steelblue") +
coord_flip() +
labs(
title = "Tiempo promedio a escuelas (500m)",
x = "Radio censal",
y = "Tiempo promedio (minutos)"
) +
theme_minimal()
df_cm <- conteo_escuelas_cm %>%
mutate(grupo = case_when(
barrios_nom == "Almagro" ~ "Clase media baja",
barrios_nom == "Caballito" ~ "Clase media",
barrios_nom == "Palermo" ~ "Clase media alta"
))
df_vul <- conteo_escuelasvul %>%
mutate(grupo = "Vulnerable")
conteo_comparado <- bind_rows(df_cm, df_vul)
tabla_comparativa <- bind_rows(tablacm_resumen, tablavul_resumen)
print(tabla_comparativa)
## # A tibble: 6 × 5
## barrios_nom `1000m` `2000m` `500m` Sum
## <chr> <int> <int> <int> <dbl>
## 1 Almagro 302 636 131 1069
## 2 Caballito 243 529 113 885
## 3 Palermo 259 563 96 918
## 4 Villa_15 70 153 49 272
## 5 Villa_21_24 57 160 24 241
## 6 Villa_31 41 151 22 214
Desde la proximidad geografica, adviertimos una notoria diferencia en cuanto a la cantidad de escuelas que los barrios vulnerables disponen. Para comenzar, los barrios de clase media y alta disponen de un total de escuelas que va desde 885 a las 1069 escuelas, contra las 214 a las 272 en el caso de los barrios vulnerables, notandose una brecha de 4 a 5 veces más escuelas alrededor de barrios medios/altos que de los vulnerables. Como dato llamativo, cabe destacar, respecto del radio cobertura mas próximo (500 metros), que el barrio de Palermo, casi lindante con el barrio de retiro, en el cual se encuentra la Villa 31 tenemos un %336 más de escuelas: a medida que el radio crece , la brecha sigue igual o mayor. Las diferencias apenas se atemperan en los otros radios, mostrando patrones de diferencia similares.
ggplot(data = conteo_comparado, aes(x = buffer, y = total, fill = grupo)) +
geom_col(position = "dodge") +
labs(
title = "Cantidad de escuelas por Radio de Cobertura y Grupo Socioeconomico",
x = "Buffer",
y = "Total de escuelas",
fill = "Grupo socioeconomico"
) +
theme_minimal()+
coord_flip()
tabla_ges_unida <- bind_rows(
tablacm_ges %>% mutate(grupo = "Media/Alta"),
tablavul_ges %>% mutate(grupo = "Vulnerable")
)
print(tabla_ges_unida)
## # A tibble: 6 × 5
## barrios_nom Estatal Privada Sum grupo
## <chr> <int> <int> <dbl> <chr>
## 1 Almagro 356 280 636 Media/Alta
## 2 Caballito 322 207 529 Media/Alta
## 3 Palermo 289 274 563 Media/Alta
## 4 Villa_15 124 29 153 Vulnerable
## 5 Villa_21_24 137 23 160 Vulnerable
## 6 Villa_31 81 70 151 Vulnerable
Respecto del tipo de gestion encontramos una brecha más amplia aun, dado que en el caso de las escuelas vulnerables la educacion estatal es casi exclusiva, alrededor deun %80, a diferencia de los sectores medios altos, donde si bien la gestion continua siendo mayoritariamente estatal, la oferta se encuenta mas balanceada, sin olvidar que se trata de una cercana a Palermo.
{rGraficos9: Escuelas por Barrio y Gestion} ggplot(tabla_ges_unida, aes(x = barrios_nom)) + geom_col(aes(y = Estatal, fill = "Estatal"), position = "dodge") + geom_col(aes(y = Privada, fill = "Privada"), position = "dodge") + scale_fill_manual( name = "Tipo de gestión", values = c("Estatal" = "#1b9e77", "Privada" = "#d95f02") ) + labs( title = "Cantidad de escuelas por barrio y tipo de gestión", x = "Barrio", y = "Total de escuelas" ) + theme_minimal()
Respecto n barrios populares casi todos los valores están concentrados entre 0 y 28 min, mientras que en barrios medios/altos, además de los tiemposmenores a los 30 minutos psexiste un subconjunto significativo que tiene 1 hora o más viaje. Es decir que en una primera instancia desde la accesibilidad geografica, las escuelas ubicadas en barrios vulnerables muestran un mayor grado.
df_tiemposcm_larga_5002 <- df_tiemposcm_larga_500 %>%
mutate(grupo = "Clase media y alta")
df_tiemposvul_larga_5002 <- df_tiemposvul_larga_500 %>%
mutate(grupo = "Vulnerable")
# Unificamos
df_tiempos_unificado_5002 <- bind_rows(df_tiemposcm_larga_5002, df_tiemposvul_larga_5002)
ggplot(df_tiempos_unificado_5002, aes(x = reorder(radio_id, tiempo_min), y = tiempo_min, fill = grupo)) +
geom_col(position = position_dodge()) +
coord_flip() +
labs(
title = "Comoparativa de Tiempo a escuelas (500m) por radio censal y grupo",
x = "Radio censal",
y = "Tiempo (minutos)",
fill = "Grupo"
) +
theme_minimal()
Por supuesto, a este analisis deben sumarsele otros factores como equipamiento de las escuelas y proporion entre cantidad de alumnos y escuelas, ademas de los recursos de movilidad propia o publica disponible en cada caso.